/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.urchr.todoist.lib;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 *
 * @author Kostya
 */
public class JSONParser{
    private char[] buffer = null;
    private int pos = 0;
    
    private char nextChar(){
        return buffer[pos++];
    }
    
    private char nextCharSkipWS(){
        char ch = nextChar();
        if(ch==' ')
            return nextCharSkipWS();
        return ch;
    }
    
    
    public JSONParser(String data){
        setData(data);
    }
    
    public void setData(String data){
        data = data.trim();
        if(data.length()==0)
            return;
        if(data.charAt(0)!='[')
            data = "["+data+"]";
        this.buffer = data.toCharArray();
        pos = 0;
    }
    
    public Vector parseData(){
        return parseVector();
    }

    private Hashtable parseHashtable(){
        Hashtable res = new Hashtable();
        char ch = nextCharSkipWS();
        do{
            ch = nextCharSkipWS();
            if(ch=='}')
                return res;
            pos--;
            String name = parseString();
            ch = nextCharSkipWS();
            if(ch==':'){
                ch = nextCharSkipWS();
                pos--;
                Object val = null;
                if(ch=='['){
                    val = parseVector();
                }
                
                if(ch=='{'){
                    val = parseHashtable();
                }
                if(val==null)
                    val = parseString();
                res.put(name, val);
            }
        }while(pos<=buffer.length);
        return res;
    }
    
    private String parseString(){
        String res = "";
        boolean isQuote = false;
        char ch = nextChar();
        if(ch=='"'){
            isQuote = true;
        }else{
            pos--;
        }
        do{
            ch = nextChar();
            if((ch=='"' && isQuote) || ((ch==',' || ch=='{' || ch=='}' || 
                    ch=='[' || ch==']' || ch==':') && !isQuote)){
                if(!isQuote)
                    pos--;
                return res;
            }
            res += ch;
        }while(pos<=buffer.length);
        return res;
    }
    
    private Vector parseVector() {
        Vector res = new Vector();
        char ch = nextChar();
        
        do{
            ch = nextCharSkipWS();
            if(ch=='['){
                pos--;
                res.addElement(parseVector());
                continue;
            }
            if(ch=='{'){
                pos--;
                res.addElement(parseHashtable());
                continue;
            }
            if(ch==',')
                continue;
            if(ch!=']'){
                pos--;
                res.addElement(parseString());
                continue;
            }
        }while(ch!=']');
        return res;
    }
    
    
    
    public void printVector(Vector v, int shift){
        String shiftStr = "";
        for (int i = 0; i < shift; i++) {
            shiftStr += " ";
        }
        System.out.println("[");
        for (int i = 0; i < v.size(); i++) {
            Object o = v.elementAt(i);
            System.out.print(shiftStr+"["+i+"] = ");
            printObject(o, shift+1);
        }
        System.out.println(shiftStr+"]");
    }

    private void printHashtable(Hashtable hashtable, int shift) {
        String shiftStr = "";
        for (int i = 0; i < shift; i++) {
            shiftStr += " ";
        }
        System.out.println("{");
        Enumeration e = hashtable.keys();
        for(;e.hasMoreElements();){
            String name = (String) e.nextElement();
            System.out.print(shiftStr+name+" = ");
            printObject(hashtable.get(name), shift+1);
        }
        System.out.println(shiftStr+"}");
    }

    private void printObject(Object o, int i) {
        if(o instanceof Vector){
            printVector((Vector)o, i);
            return;
        }
        if(o instanceof Hashtable){
            printHashtable((Hashtable)o, i);
            return;
        }
        System.out.println(o.toString());
            
    }
}

